<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      var minWindow = function (s, t) {
        /* 找出t中所有不同字符 */
        let start = Infinity
        let map = new Map()
        let missingtype = 0
        let minLength = Infinity

        for (let i = 0; i < t.length; i++) {
          if (!map.has(t[i])) {
            map.set(t[i], 1)
            missingtype++
          } else {
            map.set(t[i], map.get(t[i]) + 1)
          }
        }

        //定义滑动窗口
        let left = 0
        let right = 0
        for (; right < s.length; right++) {
          /*  不能添加这个map.get(s[right]!=0)的条件 
               当s=='bba'  t='ba'时，第一次遍历b使得b:0,messingtype--
               但是如果添加了这个条件就会导致第二次遍历到b，依然missingtype--
          */
          if (map.has(s[right])) {
            map.set(s[right], map.get(s[right]) - 1)
          }
          if (map.get(s[right]) == 0) {
            //如果该字符在map中为0，说明该类别的找齐了
            missingtype--
          }
          /* 不同的字符类别都找完了，收缩窗口 */
          while (missingtype == 0) {
            //比较窗口最小值
            if (right - left + 1 < minLength) {
              minLength = right - left + 1
              start = left
            }
            //让left指针右移动，丢失了一个原来的
            let leftChar = s[left]
            if (map.has(leftChar)) {
              map.set(leftChar, map.get(leftChar) + 1)
            }
            if (map.get(leftChar) > 0) {
              missingtype++
            }
            left++
          }
        }

        if (start == Infinity) return ''
        return s.slice(start, start + minLength)
      }
      minWindow('bba', 'ab')
    </script>
  </body>
</html>
